-- Copyright (c) 2011-2013, bkil.hu
-- This program is free software and can be distributed under the terms of
-- the GNU General Public License v2,
-- see COPYING for detailed licensing terms.
-- created on 2012-05-15 (forked from minichess)

-- GHC compiles without any annotation at all, but Hugs will need a few
type Owner = Int
type Coord = (Int,Int)
type Pieces = [(Owner,Int,Coord)]
dim :: Int
rules :: [[Coord]]
main :: IO()
turn :: Owner -> Pieces -> IO ()
value :: Int -> Owner -> Pieces -> (Int, Pieces)
steps :: Owner -> Pieces -> [Pieces]
add :: Coord -> Coord -> Maybe Coord

dim = 4

rules = [[(-2,-1), (-2,1), (-1,-2), (-1,2), (1,-2), (1,2), (2,-1), (2,1)],
         [(-1,-1), (-1,1), (1,-1), (1,1)], [(-1,0), (0,-1), (0,1), (1,0)]]

main = turn 1 [(1, 0,(0,0)), (1, 1,(1,0)), (1, 2,(2,0)),
               (-1,1,(0,3)), (-1,0,(1,3)), (-1,2,(2,3))]

turn o pieces = do
    mapM print [[head ([2*o+i+3 | (o,i,(x',y'))<-pieces, x'==x, y'==y]++[0]) |
       x <- [0..dim-1]] | y <- [0..dim-1] ]
    let (k,p') = value 8 o pieces
    print k -- debug
    if p'/=pieces then turn (-o) p' else return ()

value 0 o p = (sum $ map (\(o',t,(x,y)) -> (x+y+10*dim*(3-t))*o'*o) p,p)
value n o p = case steps o p of
    [] -> (-999-10*dim*n, p)
    ps -> maximum [(-k',p') | p' <- ps, (k',_) <- [value (n-1) (-o) p']]

steps o p = [(o,t,xy') : rest | (o',t,xy) <- p, o'==o,
             Just xy' <- map (add xy) (rules !! t),
             rest <- [filter (\(_,_,xy'')-> xy'' /= xy && xy'' /= xy') p]]

add (x,y) (u,v) | x+u>=0 && x+u<dim && y+v>=0 && y+v<dim = Just (x+u,y+v)
add _ _ = Nothing
